'''
Created on May 11, 2011

@author: bruk
'''
import os, sys
import pygame #@UnresolvedImport
from pygame.locals import *
import Settings
import Logic
import Physics
MODIFIERS = ['flip-x', 'flip-y', 'flip-xy','blink','rot-(-45)','rot-(45)']

#example animation dict
# STATE-FACING': (fps,(startframe, endframe), [modifiers])
Link = {'IDLE-FRONT':(0, (0,0),[]),
        'RUNNING-FRONT':(0, (3,12),[]),
        
        'IDLE-BACK':(0, (338,338),[]),
        'RUNNING-BACK':(0, ( 341, 350),[]),

        'IDLE-LEFT':(0, (663,663), []),
        'RUNNING-LEFT':(0, (666,675), []),
        
        'IDLE-RIGHT':(0, (663,663), ['flip-x']),
        'RUNNING-RIGHT':(0, (666,675), ['flip-x']),

        #'IDLE-FRONTLEFT':(0, (0,0),['rot-(45)']),
        #'RUNNING-FRONTLEFT':(0, (3,12),['rot-(45)']),
        
        #'IDLE-FRONTRIGHT':(0, (0,0),['flip-x','rot-(-45)']),
        #'RUNNING-FRONTRIGHT':(0, (3,12),['flip-x','rot-(-45)']),
        
        #'IDLE-BACKLEFT':(0, (338,338),['rot-(45)']),
        #'RUNNING-BACKLEFT':(0, ( 341, 350),['rot-(45)']),

        #'IDLE-BACKRIGHT':(0, (338,338),['flip-x','rot-(-45)']),
        #'RUNNING-BACKRIGHT':(0, ( 341, 350),['flip-x','rot-(-45)']),
        
        'ELEC-FRONT':(10,(60,61),[]),
        'ELEC-BACK':(10,(398,399),[]),
        'ELEC-LEFT':(10,(723,724),[]),
        'ELEC-RIGHT':(10,(723,724),['flip-x']),

        }

NaviAnimations = {'IDLE-FRONT':(0, (0,2),['reverse']),
        'RUNNING-FRONT':(0, (0,2),['reverse']),
        
        'IDLE-BACK':(0, (0,2),['reverse']),
        'RUNNING-BACK':(0, ( 0,2),['reverse']),

        'IDLE-LEFT':(0, (0,2), ['reverse']),
        'RUNNING-LEFT':(0, (0,2), ['reverse']),
        
        'IDLE-RIGHT':(0, (0,2),['reverse'] ),
        'RUNNING-RIGHT':(0, (0,2), ['reverse']),
        }
class Actor(pygame.sprite.Sprite):
    def __init__(self, name, filename, spriteWidth, spriteHeight, fps, 
                 animations, player = 0 , posx=0, posy=0, 
                 movementspeed=0.5, mass = 1.0, ghost = True):
        pygame.sprite.Sprite.__init__(self)

        self.SpriteSheet = pygame.image.load(filename).convert()
        self.SpriteSheetWidth, self.SpriteSheetHeight = self.SpriteSheet.get_size()
        self.Player = player
        self.SpriteSheetColumns = int(self.SpriteSheetWidth / spriteWidth)
        self.SpriteSheetRows = int(self.SpriteSheetHeight / spriteHeight)
        self.FrameCount = self.SpriteSheetColumns * self.SpriteSheetRows
        self.SpriteHeight = spriteHeight
        self.SpriteWidth = spriteWidth
        self.Name = name

        self.Position = [posx, posy]
        
        self._start = pygame.time.get_ticks()
        self._delay = 1000 / fps
        self._last_update = 0
        self._frame = 0
        self._images = []
        self._play_direction = 1
        i = 0
        j = 0
        self.Animations = animations
        self.State = 'IDLE'
        self.Facing = 'FRONT'
        
        
        self.Velocity = [0,0]
        self.Mass = mass
        self.MovementSpeed = movementspeed
        self.Ghost = ghost
        self.rect = pygame.Rect(posx,posy,self.SpriteWidth, self.SpriteHeight)

        
        while (i < self.SpriteSheetRows):
            while (j < self.SpriteSheetColumns):

                frame = pygame.Rect(j*self.SpriteWidth, i*self.SpriteHeight, self.SpriteWidth,self.SpriteHeight) 
                self._images.append(self.SpriteSheet.subsurface(frame))
                
                j+=1
                
            i+=1
            j = 0
        self.image = self._images[0]
            
        if Settings.DEBUGGING: 
            print '<actor:' + self.Name + '> @' + str(id(self)) + ' is initialized.'   
            


    def Think(self, *arguments, **keywords):
        pass
        
    def parseGameEvents(self,event):
        pass
    
    def MoveTo(self,x,y):
        self.Position = [x,y]
        self.rect.move(x,y)


    def MoveX(self,x):
        self.Position[0] += x
        self.rect.x += x
        
    def MoveY(self,y):
        self.Position[1] += y
        self.rect.y += y
    
    #TODO: maybe have pre and post modifiers to limit looping 
    def update(self, t):
        currentAnimation = self.Animations[self.State + '-' + self.Facing]
        delay = self._delay
        if currentAnimation[0] != 0:
            delay = 1000 / currentAnimation[0] 
                    
        if t - self._last_update > delay:
            self._frame += 1 * self._play_direction
            
            reversethis = 'reverse' in currentAnimation[2]
            #which animation are we playing?
            if self._frame < currentAnimation[1][0]: 
                if reversethis:
                    self._play_direction = 1
                    
                self._frame = currentAnimation[1][0]
            
            if self._frame > currentAnimation[1][1]:
                if reversethis:
                    self._play_direction = -1
                    self._frame = currentAnimation[1][1]
                else:
                    self._frame = currentAnimation[1][0]
            

            #print self._frame
                        
            self.image = self._images[self._frame]
            
            #is there any need to apply flags?
            for mod in currentAnimation[2]:
                if mod == 'flip-x':
                    self.image = pygame.transform.flip(self.image, True, False)
                elif mod == 'flip-y':
                    self.image = pygame.transform.flip(self.image, False, True)
                elif mod == 'flip-xy':
                    self.image = pygame.transform.flip(self.image, True, True)
                if mod == 'rot-(45)':
                    self.image = pygame.transform.rotate(self.image, -45.0)
                #pygame rotates counter clockwise!
                if mod == 'rot-(-45)':
                    self.image = pygame.transform.rotate(self.image, 45.0)
 

            self._last_update = t

class NPC(Actor):
    def __init__(self, name, filename, spriteWidth, spriteHeight, fps, animations, posx=0, posy=0, movementspeed = 1):
        Actor.__init__(self, name, filename, spriteWidth, spriteHeight, fps, animations, 0, posx, posy, movementspeed, ghost=False)
    
    def Think(self,*arguments, **keywords):
            Actor.Think(self)

class Player(Actor):
    

    def __init__(self, filename, spriteWidth, spriteHeight, fps, animations, posx=0, posy=0):
        Actor.__init__(self,'Player', filename, spriteWidth, spriteHeight, fps, animations, 1, posx, posy, ghost=False, movementspeed=1)
    
    def Think(self,*arguments, **keywords):
        
        #KEYBOARD EVENTS
        Logic.PlayerControl(self, keywords['events'])
        
        
        #PHYSICS
        Actor.Think(self)


        
                
class Navi(NPC):
    def __init__(self):
        NPC.__init__(self, 'Navi', '/home/bruk/Code fu/steampunked/Resources/navi2.png',
                     22,14, 7, NaviAnimations, 320,320)
        
        self.Ghost = False
        
    def Think(self, *arguments, **keywords):
        #follow the player!
        #Logic.GhostTrackTo( self, keywords['player'].Position, 10)
        NPC.Think(self, *arguments, **keywords)
        